package com.wmsafe.order.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wmsafe.common.enums.ResponseCodeEnum;
import com.wmsafe.common.po.Person;
import com.wmsafe.common.utils.FileUtils;
import com.wmsafe.common.utils.RedisUtil;
import com.wmsafe.common.utils.ResponseData;
import com.wmsafe.order.entity.Order;
import com.wmsafe.order.excelService.ExcelExportService;
import com.wmsafe.order.excelService.ExcelExportServiceNew;
import com.wmsafe.order.excelService.ExportService;
import com.wmsafe.order.mapper.OrderMapper;
import com.wmsafe.order.service.IOrderService;
import com.wmsafe.order.utils.RocketMqHelper;
import org.apache.poi.ss.formula.functions.T;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 订单服务 Controller业务类
 * @author 大白有点菜
 * @className OrderController
 * @date 2023-03-31
 * @description
 * @since 1.0
 **/
@RestController
@RequestMapping("order")
public class OrderController {
    @Autowired
    private IOrderService orderService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RocketMqHelper rocketMqHelper;

    /**
     * 通过订单号获取数据
     * @param orderNum 订单号
     * @return
     */
    @GetMapping("/queryByOrderNum/{orderNum}")
    public ResponseData queryByOrderNum(@PathVariable String orderNum) {
        Order order = orderService.getByOrderNum(orderNum);

        /**
         * mybatis plus 新增的写法 可以用sql构造器构造sql语句（链式编程）
         */
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_phone", "17512013929");
        List<Order> list = orderService.list(queryWrapper);

        return order == null ? ResponseData.success(ResponseCodeEnum.NULL_DATA.getCode())
                : ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), order);
    }

    /**
     * 通过主键ID获取数据
     * @param id 主键ID
     * @return
     */
    @GetMapping("/queryById/{id}")
    public ResponseData queryById(@PathVariable Long id) {
        Order order = orderService.getById(id);
        return order == null ? ResponseData.success(ResponseCodeEnum.NULL_DATA.getCode())
                : ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), order);
    }

    /**
     * 新增
     * @param order 支付服务实体对象
     * @return
     */
    @PostMapping("/add")
    public ResponseData add(@RequestBody @Validated Order order) {
        int addResult = orderService.add(order);
        return addResult > 0 ? ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), null, "新增数据成功")
                : ResponseData.error(ResponseCodeEnum.ERROR.getCode(), "新增数据失败");
    }

    /**
     * 通过订单号删除数据
     * @param orderNum 订单号
     * @return
     */
    @GetMapping("/deleteByOrderNum/{orderNum}")
    public ResponseData deleteByOrderNum(@PathVariable String orderNum) {
        int deleteResult = orderService.deleteByOrderNum(orderNum);
        return deleteResult > 0 ? ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), null, "删除数据成功")
                : ResponseData.error(ResponseCodeEnum.ERROR.getCode(), "删除数据失败");
    }

    /**
     * 通过主键ID删除数据
     * @param id 主键ID
     * @return
     */
    @GetMapping("/deleteById/{id}")
    public ResponseData deleteById(@PathVariable Long id) {
        int deleteResult = orderService.deleteById(id);
        return deleteResult > 0 ? ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), null, "删除数据成功")
                : ResponseData.error(ResponseCodeEnum.ERROR.getCode(), "删除数据失败");
    }

    @Autowired
    private ExcelExportService excelExportService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ExportService exportService;


    @GetMapping("/excel/orderTest")
    public void exportReport(HttpServletResponse response) throws IOException {
//        Class<?> entityClass = Order.class; // 指定实体类
//        excelExportService.exportExcel(entityClass, response);

//        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
////        queryWrapper.eq("user_name", "123"); // 设置自定义的查询条件
//
//        ExcelExportServiceNew.exportToExcel(Order.class, orderMapper,"OrderExcelData", response, queryWrapper);

        // 调用导出方法
        String fileName = "data.xlsx";
        int batchSize = 100;

        try {
            // 设置响应头信息
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            //自定义sql条件导出
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            // 调用服务导出数据
            exportService.exportData(fileName, orderMapper,queryWrapper, batchSize);

            // 将导出文件写入响应流
            OutputStream out = response.getOutputStream();
            FileInputStream fis = new FileInputStream(fileName);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            fis.close();
            out.flush();

            // 删除临时文件
            File file = new File(fileName);
            CompletableFuture<Boolean> deleteFuture = FileUtils.deleteFileAsync(file);
            deleteFuture.thenAccept(deleted -> {
                if (deleted) {
                    System.out.println("文件删除成功");
                } else {
                    System.out.println("文件删除失败");
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    @GetMapping("/testRedisDemo")
    public ResponseData testRedisDemo() {

        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        redisUtil.set("kuchun","100");//库存

        Person person = new Person();
        person.setName("heyuhua");
        person.setAge(25);

        rocketMqHelper.asyncSend("PERSON_ADD", MessageBuilder.withPayload(person).build());

        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("wmsafe","666");
        jsonArray.add(jsonObject);
        System.out.println(jsonArray.toJSONString());

        return ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), null, "testRedisDemo");
    }

    @GetMapping("/testRedisSonLock") //测试分布式锁
    public ResponseData testRedisSonLock() {
        String lockKey = "lockKey";
        RLock lock = redissonClient.getLock(lockKey);
        try {
            RedisUtil redisUtil = new RedisUtil();
            redisUtil.setRedisTemplate(redisTemplate);
            //尝试拿到锁 没拿到返回false
            if (lock.tryLock()) {
                String kuchun = redisUtil.get("kuchun");
                int count = Integer.parseInt(kuchun);

                if (count <= 0) {
                    throw new RuntimeException("商品已经卖完了，下次再来吧！");
                }
                System.out.println("count的值：" + count--);
                redisUtil.set("kuchun", String.valueOf(count));
                return ResponseData.success(ResponseCodeEnum.SUCCESS.getCode(), null, "testRedisSonLock");
            }else{
                return ResponseData.error(ResponseCodeEnum.ERROR.getCode(), "拿锁失败，请稍候再试");
            }
        } finally {
            unlock(lockKey);
        }
    }

    public void unlock(String lockKey) {
        try {
            RLock lock = redissonClient.getLock(lockKey);
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        } catch (Throwable e) {
            String msg = String.format("UNLOCK FAILED: key=%s", lockKey);
            throw new IllegalStateException(msg, e);
        }
    }


}
